package com.my.study.permission.tree.utils;

import com.my.study.permission.tree.TreeRsVo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

/**
 * @author: Carlos
 * @create: 2021/01/11 20:18
 */
public class TreeUtils {

    /**
     * 构造树
     *
     * @param list
     * @param supplier
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static <T extends TreeRsVo> T tree(List<T> list, Supplier<T> supplier) {
        //组装Map数据,将所有菜单全部放到Map中，并用菜单ID作为Key来标记，方便后面的各节点寻找父节点。
        Map<Long, T> dataMap = new HashMap<>(16);
        for (T tree : list) {
            dataMap.put(tree.getId(), tree);
        }
        // 创建根节点
        T root = supplier.get();
        //组装树形结构，将子节点全部挂靠到自己的父节点
        for (Map.Entry<Long, T> entry : dataMap.entrySet()) {
            T tree = entry.getValue();
            if (tree.getParentId().equals(0L)) {
                if (root.getChildren() == null) {
                    root.setChildren(new ArrayList());
                }
                root.getChildren().add(tree);
            } else {
                if (dataMap.get(tree.getParentId()).getChildren() == null) {
                    dataMap.get(tree.getParentId()).setChildren(new ArrayList());
                }
                dataMap.get(tree.getParentId()).getChildren().add(tree);
            }
        }
        //对多级树形结构进行“二叉树排序”
        root.sortChildren();
        return root;
    }
}
